package com.fnzn.entranceGuard.util;

import com.fnzn.entranceGuard.constant.DeviceTypeContant;
import com.fnzn.entranceGuard.entity.GuardDevice;
import com.fnzn.entranceGuard.entity.QR;
import com.fnzn.entranceGuard.entity.community.CommunityInfo;
import com.fnzn.entranceGuard.entity.sys.SysUserRole;
import com.fnzn.entranceGuard.service.community.ICommunityInfoService;
import com.fnzn.entranceGuard.service.sys.SysDeptService;
import com.fnzn.entranceGuard.service.sys.SysUserService;
import com.fnzn.entranceGuard.vo.UnitHouseVo;
import com.github.pig.common.util.SymmetricEncoder;
import com.github.pig.common.vo.UserVO;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * 二维码生成  解析工具
 *
 * @author wf_sxf@163.com
 * @date 2018-05-28 11:04
 */
public class QRGenerate {
    private final static String SECRET = "FNZN";
    private final static String HEADER = "QR";
    /**
     * 定义物业管理人员类型常量
     */
    private final static String TYPE = "1";

    /**
     * 初始化
     *
     * @param userName,communityId,expiredTime
     * @return
     */
    public static String generate(String userName, String communityId, String expiredTime) {

        ICommunityInfoService communityInfoService = SpringUtil.getBean(ICommunityInfoService.class);
        SysUserService sysUserService = SpringUtil.getBean(SysUserService.class);
        // 根据小区id获取到小区对象
        CommunityInfo communityInfo = communityInfoService.selectById(communityId);
        // 判断是否为空
        if (communityInfo == null) {
            return nullContent(expiredTime);
        }
        // 获取到小区编号
        Integer code = communityInfo.getId();
        if (code == null) {
            return nullContent(expiredTime);
        }
        // 根据小区编号分出前两个字节
        if (code > 9999) {
            return nullContent(expiredTime);
        }
        StringBuffer sb = new StringBuffer();
        Integer first = code / 100;
        Integer second = code % 100;
        if (first < 10) {
            sb.append("0" + first);
        } else {
            sb.append(first);
        }
        if (second < 10) {
            sb.append("0" + second);
        } else {
            sb.append(second);
        }
        // 第三个字节 n 权限内设备个数 0-99
        //如果是该小区的物业管理员角色 则放99
        List<UserVO> userList = sysUserService.findEstatesByUsername(userName, communityId);
        if (userList!=null && userList.size() > 0) {
            sb.append(99);
            // 第四个字节---第七个字节
            sb.append(expiredTime);
            // 第八到8+n个字节 放设备编号
            sb.append(99);
            // 第8+n到8+2n个字节 放楼层
            sb.append(99);
        } else {
            //业主
            // 根据用户和小区id获取到角色id集合
            List<SysUserRole> roleIdList = communityInfoService.getRoleId(userName, communityId);
            if (roleIdList.size() == 0 || roleIdList == null) {
                return nullContent(expiredTime);
            }
            // 定义权限内的设备个数为sum
            Integer sumDevices = 0;
            // 定义设备编号字符串
            StringBuffer str = new StringBuffer("");
            // 设备总楼层数
            StringBuffer floor = new StringBuffer();
            // 遍历角色id集合
            for (SysUserRole roleList : roleIdList) {
                if(StringUtils.isBlank(roleList.getRoleId())){
                    continue;
                }
                String[] rIds = roleList.getRoleId().split(",");
                // 获取到设备集合
                List<GuardDevice> deviceList = new ArrayList<>();
                for (String rid : rIds){
                    List<GuardDevice> list = communityInfoService.getDeviceId(rid);
                    deviceList.addAll(list);
                }
                // 遍历集合
                for (int i = 0; i < deviceList.size(); i++) {
                    // 拼接设备编号
                    if (deviceList.get(i).getSort() == null) {
                        str.append("00");
                    } else if (deviceList.get(i).getSort() < 10) {
                        str.append("0" + deviceList.get(i).getSort());
                    } else if (deviceList.get(i).getSort() > 9 && deviceList.get(i).getSort() < 100) {
                        str.append(deviceList.get(i).getSort());
                    } else {
                        str.append(99);
                    }
                    // 拼接楼层
                    String floorId = deviceList.get(i).getGuardId();
                    String type = deviceList.get(i).getDeviceType();
                    if(GuardDevice.TYPE_ELE.equals(deviceList.get(i).getType())){
                        // 梯控，查询设备父级，获取floorID
                        //查询楼层数
                        if (DeviceTypeContant.BUILDING.equals(type) || DeviceTypeContant.unit.equals(type)) {
                            List<UnitHouseVo> houseList = communityInfoService.getHouseByBuilderId(floorId, userName, type);
                            if (houseList == null || houseList.size() == 0) {
                                floor.append("00");
                            } else if (houseList.size() > 1) {
                                floor.append("99");
                            } else {
                                //如果楼层为0
                                if(houseList.get(0).getFloor() == 0){
                                    floor.append("99");
                                }else if (houseList.get(0).getFloor() < 10) {
                                    floor.append("0" + houseList.get(0).getFloor());
                                } else {
                                    floor.append(houseList.get(0).getFloor());
                                }
                            }
                        } else {
                            floor.append("00");
                        }
                    }else{
                        //不是梯控  返回00
                        floor.append("00");
                    }
                }
                // 累加所有角色下的设备数
                sumDevices += deviceList.size();
            }
            //拼接
            if (sumDevices < 10) {
                sb.append("0" + sumDevices);
            } else {
                sb.append(sumDevices);
            }
            // 第四个字节---第七个字节
            sb.append(expiredTime);
            // 第八到8+n个字节 放设备编号
            sb.append(str);
            // 第8+n到8+2n个字节 放楼层
            sb.append(floor);
        }
        System.out.println(sb.toString());
        return sb.toString();
    }
    /**
     * 初始化  --  企业二维码
     *
     * @param userName,communityId,expiredTime
     * @return
     */
    public static String generateCompany(String userName,  Integer companyId, String expiredTime) {

        ICommunityInfoService communityInfoService = SpringUtil.getBean(ICommunityInfoService.class);
        SysDeptService deptService = SpringUtil.getBean(SysDeptService.class);
        SysUserService sysUserService = SpringUtil.getBean(SysUserService.class);

        // 根据小区编号分出前两个字节
        if (companyId > 9999) {
            return nullContent(expiredTime);
        }
        StringBuffer sb = new StringBuffer();
        Integer first = companyId / 100;
        Integer second = companyId % 100;
        if (first < 10) {
            sb.append("0" + first);
        } else {
            sb.append(first);
        }
        if (second < 10) {
            sb.append("0" + second);
        } else {
            sb.append(second);
        }
        // 第三个字节 n 权限内设备个数 0-99
        //如果是该企业的管理员角色 则放99
        List<UserVO> userList = sysUserService.findEstatesByUsername(userName, companyId.toString());
        if (userList!=null && userList.size() > 0) {
            sb.append(99);
            // 第四个字节---第七个字节
            sb.append(expiredTime);
            // 第八到8+n个字节 放设备编号
            sb.append(99);
            // 第8+n到8+2n个字节 放楼层
            sb.append(99);
        } else {
            //职工
            // 根据用户和小区id获取到角色id集合
            List<SysUserRole> roleIdList = communityInfoService.getRoleIdByCompany(userName, companyId);
            if (roleIdList.size() == 0 || roleIdList == null) {
                return nullContent(expiredTime);
            }
            // 定义权限内的设备个数为sum
            Integer sumDevices = 0;
            // 定义设备编号字符串
            StringBuffer str = new StringBuffer("");
            // 设备总楼层数
            StringBuffer floor = new StringBuffer();
            // 遍历角色id集合
            for (SysUserRole roleList : roleIdList) {
                if(StringUtils.isBlank(roleList.getRoleId())){
                    continue;
                }
                String[] rIds = roleList.getRoleId().split(",");
                // 获取到设备集合
                List<GuardDevice> deviceList = new ArrayList<>();
                for (String rid : rIds){
                    List<GuardDevice> list = communityInfoService.getDeviceId(rid);
                    deviceList.addAll(list);
                }
                // 遍历集合
                for (int i = 0; i < deviceList.size(); i++) {
                    // 拼接设备编号
                    if (deviceList.get(i).getSort() == null) {
                        str.append("00");
                    } else if (deviceList.get(i).getSort() < 10) {
                        str.append("0" + deviceList.get(i).getSort());
                    } else if (deviceList.get(i).getSort() > 9 && deviceList.get(i).getSort() < 100) {
                        str.append(deviceList.get(i).getSort());
                    } else {
                        str.append(99);
                    }
                }
                // 累加所有角色下的设备数
                sumDevices += deviceList.size();
            }
            //拼接
            if (sumDevices < 10) {
                sb.append("0" + sumDevices);
            } else {
                sb.append(sumDevices);
            }
            // 第四个字节---第七个字节
            sb.append(expiredTime);
            // 第八到8+n个字节 放设备编号
            sb.append(str);
            // 第8+n到8+2n个字节 放楼层
            sb.append(floor);
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

    /**
     * 拼接二维码是如果数据出错  返回信息
     * @param expired
     * @return
     */
    public static String nullContent(String expired) {
        StringBuilder sb = new StringBuilder("000000");
        sb.append(expired);
        return sb.toString();

    }
    /**
     * 将字符串中的时间以十进制转出
     *
     * @param content
     * @return
     */
    public static byte[] generateQr(String content) {
        byte[] data = parseStr2HexByte(content);
        String date = content.substring(6, 14);
        byte[] d = parse16Str2HexByte(date);
        data[3] = d[0];
        data[4] = d[1];
        data[5] = d[2];
        data[6] = d[3];
        return data;

    }

    /**
     * 输出最大时间以十进制转出
     *
     * @param content
     * @return
     */
    public static byte[] generateQrMost(String content) {
        byte[] data = parseStr2HexByte(content);

        byte[] d = parse16Str2HexByte("31235959");
        data[3] = d[0];
        data[4] = d[1];
        data[5] = d[2];
        data[6] = d[3];
        return data;

    }

    /**
     * 解析
     *
     * @param hex
     * @return
     */
    public static QR analysis(String hex) {

        try {
            //base64解码
            String base64 = new String(Base64.getDecoder().decode(hex), "UTF-8");
            //aes解密
            String aes = SymmetricEncoder.AESDncode(SECRET, base64);

            String[] content = aes.split("\\$");
            if (content.length > 0 && content[0].equals(HEADER)) {
                //二维码
                if (content.length > 4 && Boolean.valueOf(content[5])) {
                    //分享二维码
                    return new QR(content[1], content[2], content[3], true, content[5]);
                } else {
                    //自主二维码
                    return new QR(content[1], content[2], content[3], false, "");
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将数字字符串转换为16进制byte
     * 例：112030 转[0b,14,1e]
     *
     * @param hexStr
     * @return
     */
    public static byte[] parseStr2HexByte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            Integer temp = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2));
            result[i] = (byte) Integer.parseInt(Integer.toHexString(temp), 16);
        }
        return result;
    }

    /**
     * 将字符串转为asc码字符串
     */
    public static String StringToAsciiString(String content) {
        String result = "";
        int max = content.length();
        for (int i = 0; i < max; i++) {
            char c = content.charAt(i);
            String b = Integer.toHexString(c);
            result = result + b;
        }
        return result;
    }
    //ascii转换为string
    public static String AToString(byte[] bytes){
        StringBuffer sb = new StringBuffer();
        for (int i=0;i<bytes.length;i++){
            sb.append((char)bytes[i]);
        }
        return sb.toString();
    }

    /**
     * 将16进制字符串转换为16进制byte
     * 例：b1 b2 b3 转[b1,b2,b3]
     *
     * @param hexStr
     * @return
     */
    public static byte[] parse16Str2HexByte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            result[i] = (byte) Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
        }
        return result;
    }
    /**
     * 将16进制数转换为10进制int
     * 例：入参0x31  出参49
     *
     * @param hexStr
     * @return
     */
    public static Integer parse16HexByteToInt(byte hexStr) {
        return Integer.parseInt(Integer.toHexString(Integer.valueOf(hexStr)), 16);
    }
    /**
     * 将16进制字符串转换为10进制int
     * 例：入参0x31  出参49
     *
     * @param hexStr
     * @return
     */
    public static Integer parse16HexByteToInt(String hexStr) {
        return Integer.parseInt(Integer.toHexString(Integer.valueOf(hexStr)), 16);
    }

    /**
     * 将16进制数转换为10进制两位字符串
     * 例：入参0x01  出参01
     *
     * @param hexStr
     * @return
     */
    public static String parse16HexByte2Str(byte hexStr) {
        Integer i = Integer.parseInt(Integer.toHexString(Integer.valueOf(hexStr)), 16);
        if (i < 10) {
            return "0" + i;
        }
        return i.toString();
    }

    /**
     * 将16进制Byte数组转换为16进制两位字符串
     * 例：入参0x01  出参01
     *
     * @param hex
     * @return
     */
    public static String parse16Byte2Str(byte[] hex) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < hex.length; i++) {
            String str = Integer.toHexString(hex[i] & 0xff);
            if (str.length() == 1) {
                str = "0" + str;
            }
            sb.append(str);
        }
        return sb.toString();
    }


    public static void main(String[] args) throws Exception {
        int parseInt = Integer.parseInt("cc", 16);
        //byte[] b = parseStr2HexByte("ff");
       // System.out.println(generateQr("0001013023595999"));
//        String hexString = Integer.toHexString(parseInt);
//        System.out.println(hexString);
//        System.out.println(parse16Str2HexByte("bcb1b2b3b4b5b6b7b8b9")[0]);
        //QRGenerate.analysis(QRGenerate.generate("3rrr", "15819938-e7d9-45d0-a332-c057cf04e2eb", DateTools.getCurrentSysData(DateTools.FULL_FORMAT)));
//        GuardDevice device = new GuardDevice();
//        device.setFloor(2);
//        device.setSort(13);
//
//        byte[] b =  UsrUtil.PublishFormat(UsrUtil.communityCodeFormat(15,device), GuardConstant.TYPE_COM);
//
//        System.out.println(b);
        System.out.println(Integer.parseInt("0102",16));

    }
    //16进制和校验
    public static String makeChecksum(String data) {
        if (data == null || data.equals("")) {
            return "";
        }
        int total = 0;
        int len = data.length();
        int num = 0;
        while (num < len) {
            String s = data.substring(num, num + 2);
            System.out.println(s);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
        /**
         * 用256求余最大是255，即16进制的FF
         */
        int mod = total % 256;
        String hex = Integer.toHexString(mod);
        len = hex.length();
        // 如果不够校验位的长度，补0,这里用的是两位校验
        if (len < 2) {
            hex = "0" + hex;
        }
        return hex;
    }

}
